from django.shortcuts import render, get_object_or_404, redirect
from django.http import HttpResponse, HttpResponseRedirect
from django.contrib.auth.decorators import login_required
from django.contrib.auth import authenticate, login, logout
from machine.models import Problem, Submission, Coder, TestCase, Category, Tag, Post
from machine.forms import UserForm, ProblemForm, SubmissionForm
from machine.tasks import evaluate_submission
import re
import markdown
from django.utils.text import slugify
from markdown.extensions.toc import TocExtension

def index(request):
    return render(request, "machine/index.html")

def about(request):
    return render(request,"machine/about.html")

def djangoblog(request):
	post_list = Post.objects.all().order_by('-created_time')
	return render(request,'blogs/index.html', context={'post_list': post_list})

def detail(request, pk):
	post = get_object_or_404(Post,pk=pk)
	md = markdown.Markdown(extensions=[
						 	'markdown.extensions.extra',
						 	'markdown.extensions.fenced_code',
#						 	'markdown.extensions.codehilite',
						 	'markdown.extensions.toc',
						 	TocExtension(slugify=slugify),
					   ])
	post.body = md.convert(post.body)
	m = re.search(r'<div class="toc">\s*<ul>(.*)</ul>\s*</div>', md.toc, re.S)
	post.toc = m.group(1) if m is not None else ''
	return render(request, 'blogs/detail.html', context={'post':post})

def archive(request, year, month):
	post_list = Post.objects.filter(created_time__year = year,
							  created_time__month = month
							  ).order_by('-created_time')
	return render(request, 'blogs/index.html', context={'post_list': post_list})

def tag(request,pk):
	t = get_object_or_404(Tag, pk=pk)
	post_list = Post.objects.filter(tags=t).order_by('-created_time')
	return render(request,'blogs/index.html',context={'post_list':post_list})

def games(request):
    return render(request,"machine/index.html")

def message(request):
    return render(request,"machine/message.html")

def login_codeuser(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        user = authenticate(username=username,password=password)
        if user is not None:
            login(request,user)
            return redirect('/')
        else:
            return render(request,'machine/login.html',{'message':'账号或密码错误！'})
    else:
        return render(request,'machine/login.html',{'message':'^_^'})

def register(request):
    registered = False
    if request.method == 'POST':
        avatar = request.FILES.get('avatar')
        user_form = UserForm(data=request.POST)
        if user_form.is_valid():
            u = user_form.save()
            u.set_password(u.password)
            u.save()
            coder = Coder(user = u)
            coder.avatar = avatar
            coder.link = '/users/%s' % (u.username)
            coder.score = 0
            coder.rank = -1
            for k in Coder.objects.all():
                coder.rank=max(coder.rank,k.rank)
            coder.save()
            registered = True
        else:
            print(user_form.errors)
    else:
        user_form = UserForm()
    return render(request,'machine/register.html',{"user_form":user_form,"registered":registered})

def logout_codeuser(request):
    if request.user.is_authenticated:
        logout(request)
    return redirect('/')

def add_problem(request):
    # if user is not logged in, throw him to a sign-in page
    if not request.user.is_authenticated:
        return redirect("/login/")
    else:
        if request.method == 'POST':
            problem_form = ProblemForm(request.POST, request.FILES)
            if problem_form.is_valid():
                # save a new problem
                problem = problem_form.save()
                problem.link = "/machine/problems/%s" % (problem.code)
                problem.author = Coder.objects.get(user = request.user)
                problem.save()
                # link the added test case to the problem and save the test case to db
                #test = TestCase(problem = problem, input_file = request.FILES['input1'],
                #           output_file = request.FILES['output1'])
                test = TestCase(problem = problem ,input_file = request.FILES.get("input1"), output_file = request.FILES.get("output1"))
                #test = TestCase(problem = problem ,input_file = "/home/iuk/xkoj/testcases/a1.in",output_file = "/home/iuk/xkoj/testcases/a1.out")
                test.save()
            return redirect("/")
        else:
            # instantiate a new ProblemForm and then render the addproblem page
            problem_form = ProblemForm()
            return render(request, "machine/addproblem.html", {"problem_form": problem_form})

def view_problem(request, pid):
    problem = get_object_or_404(Problem, code = pid)
    payload = {"problem":problem}
    return render(request, "machine/problem.html", payload)

def all_problems(request):
    problems = Problem.objects.all()
    return render(request, "machine/all.html", {"problems":problems})

def submit_code(request, pid):
    if not request.user.is_authenticated:
        return redirect('/login/')
    else:
        if request.method == 'POST':
            sub_form = SubmissionForm(request.POST)
            if sub_form.is_valid():
                sub = sub_form.save()
                sub.problem = Problem.objects.get(code = pid)
                sub.submitter = Coder.objects.get(user = request.user)
                sub.save()
                evaluate_submission.delay(sub.id)
            else:
                payload = {"sub_form":sub_form,"pid":pid}
                return render(request,"machine/submit.html",payload)
            return redirect('/submission/{}'.format(sub.id))
        else:
            sub_form = SubmissionForm()
            payload = {"sub_form":sub_form, "pid":pid}
            return render(request, "machine/submit.html", payload)

def view_submission(request, submission_id):
    required_sub = get_object_or_404(Submission, id = int(submission_id))
    if not required_sub.private or (required_sub.private and required_sub.submitter.user.username == request.user.username):
        return render(request, "machine/submission.html", {"submission": required_sub})
    else:
        return redirect('/')
